#!/usr/bin/evn python
#-*- coding: utf-8 -*-
##############################################################################
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
##############################################################################
#
# Description: A pyglet sample on how to make a tiled map.
# Author: Kao Cardoso Félix
#
#   Send any questions or suggestions to 'kcfelix [at] gmail [dot] com'
#
##############################################################################
import sys
import math

import pyglet
from pyglet.sprite import Sprite
from pyglet.gl import *

class TileSet(object):
    """This class represents a indexed set of tiles."""
    tile_w = 32
    tile_h = 32
    
    def __init__(self, image_name):
        """Build a new tileset from an image file"""
        self.tiles = pyglet.resource.image(image_name)
        self.size = (self.tiles.width / self.tile_w) * \
            (self.tiles.height / self.tile_h)
        
        # Number of tiles on x and y directions
        self._tiles_x = self.tiles.width / self.tile_w
        self._tiles_y = self.tiles.height / self.tile_h
    
    def __getitem__(self, n):
        """Returns a tile by it's index."""
        (y, x) = divmod(n, self._tiles_x)
        
        # Invert y to start at the top left tile
        #
        y = (self._tiles_y - 1) - y
            
        (w, h) = self.tile_w, self.tile_h
        x *= w
        y *= h
        
        return self.tiles.get_region(x, y, w, h)
    
class TileLayer(object):
    def __init__(self, tileset, map):
        self.tileset = tileset
        self.map = map
        self.batch = pyglet.graphics.Batch()
    
        self.sprites = []
        
        tile_w, tile_h = self.tileset.tile_w, self.tileset.tile_h
        
        for x, row in enumerate(map):
            for y, index in enumerate(row):
                tile = self.tileset[index]
                self.sprites.append( Sprite(tile, x*tile_w, y*tile_h, batch=self.batch) )
    
    def _draw_region(self, x, y, w, h):
        #tile_w, tile_h = self.tileset.tile_w, self.tileset.tile_h
        #
        #x1_map = int( math.floor(float(x) / tile_w) )
        #y1_map = int( math.floor(float(y) / tile_h) )
        #
        #x2_map = int( math.ceil(float(x + w) / tile_w) )
        #y2_map = int( math.ceil(float(y + h) / tile_h) )
        #
        #offset_x = float(x) - x1_map * tile_w
        #offset_y = float(y) - y1_map * tile_w
        #
        #sprites = []
        #
        #for x_map in range(x1_map, x2_map + 1):
        #    for y_map in range(y1_map, y2_map + 1):
        #        tile = self.tileset[self.map[x_map][y_map]]
        #        
        #        x = (x_map - x1_map) * tile_w - offset_x
        #        y = (y_map - y1_map) * tile_h - offset_y
        #        
        #        sprites.append( Sprite(tile, x,y, batch=self.batch) )
        glPushMatrix()
        glTranslatef(-x, -y, 0)
        self.batch.draw()
        glPopMatrix()



if __name__ == '__main__':
    import pickle
    import random
    
    from pyglet.window import key
    
    map_data =  pickle.load(file('map_data')) #[[random.randint(0, 5) for i in range(50) ] for j in range(50)]
    
    tileset = TileSet('tiles.png')
    layer = TileLayer(tileset, map_data)
    
    view_x, view_y = 0, 0

    win = pyglet.window.Window()

    # Create a keyboard handler for input checking
    keyboard = key.KeyStateHandler()
    win.push_handlers(keyboard)

    @win.event
    def on_draw():
        win.clear()
        layer._draw_region(view_x, view_y, 640, 480)

    def handle_input(dt):
        global view_x, view_y
        
        speed = 100.0
        
        if keyboard[key.UP]:
            view_y += speed * dt
        if keyboard[key.RIGHT]:
            view_x += speed * dt
        if keyboard[key.LEFT]:
            view_x -= speed * dt
        if keyboard[key.DOWN]:
            view_y -= speed * dt
        
    pyglet.clock.schedule_interval(handle_input, 1/60.0)
    pyglet.app.run()
